from logging import Logger

from x_pc.db.source import Session
from x_pc.db.source.model import DeliveryWorkQueue, InteriorWorkQueue, PreworkWorkQueue, TallyWorkQueue
from x_pc.model.model import TaskSource


class DeliveryWorkService(object):
    """
    发货任务
    """

    @staticmethod
    def get_work_queue(ids: list[str]) -> list[DeliveryWorkQueue]:
        """
        获取 发货任务
        :param ids:
        :return:
        """
        if ids:
            with Session() as sess:
                return sess.query(DeliveryWorkQueue).filter(DeliveryWorkQueue.task_id.in_(ids)).order_by(
                    DeliveryWorkQueue.vehicle_task_begin_time.asc()).all()
        return []

    @staticmethod
    def update_data_v2(saved_queue_list: list[tuple[str, str]],
                       taskids_tuple: tuple[list[str], list[str], list[str], list[str],],
                       logger: Logger):
        """
        母任务 状态回写
        """
        # 全部的任务ID
        delivery_ids, interior_ids, prework_ids, tally_ids = [_ if _ else [] for _ in taskids_tuple]
        if not saved_queue_list and not delivery_ids and not interior_ids and not prework_ids and not tally_ids:
            logger.warning('[PC] 母任务状态回写 无数据')
            return

        s_delivery_ids, s_interior_ids, s_prework_ids, s_tally_ids = [], [], [], []
        for sq in saved_queue_list:
            command_group_code = sq[0]
            task_id = sq[1]
            if command_group_code == TaskSource.DELIVERY.value:
                s_delivery_ids.append(task_id)
            elif command_group_code == TaskSource.INTERIOR.value:
                s_interior_ids.append(task_id)
            elif command_group_code == TaskSource.PREWORK.value:
                s_prework_ids.append(task_id)
            elif command_group_code == TaskSource.TALLY.value:
                s_tally_ids.append(task_id)

        with (Session() as sess):
            try:
                sess.begin()
                for ids, sids, queue in ((delivery_ids, s_delivery_ids, DeliveryWorkQueue),
                                         (interior_ids, s_interior_ids, InteriorWorkQueue),
                                         (prework_ids, s_prework_ids, PreworkWorkQueue),
                                         (tally_ids, s_tally_ids, TallyWorkQueue)):
                    fail_ids = [id_ for id_ in ids if id_ not in sids]
                    success_ids = [id_ for id_ in ids if id_ in sids]
                    # 批量修改状态
                    if fail_ids:
                        sess.query(queue).filter(queue.task_id.in_(fail_ids)).update({queue.state: 99},
                                                                                     synchronize_session='fetch')
                    if success_ids:
                        sess.query(queue).filter(queue.task_id.in_(success_ids)).update({queue.state: 2},
                                                                                        synchronize_session='fetch')
                # 提交事务
                sess.commit()
                info_msg = f'[PC] 母任务状态回写 总数: 发货->{len(delivery_ids)}, 在库->{len(interior_ids)}, 预作业->{len(prework_ids)}, 理货->{len(tally_ids)}'
                logger.info(info_msg)
            except Exception as ex:
                warning_msg = f'[PC] 母任务状态回写 保存数据发生错误: {ex}'
                logger.warning(warning_msg)
                sess.rollback()


class InteriorWorkService(object):
    """
    在库任务
    """

    @staticmethod
    def get_work_queue(ids: list[str]) -> list[InteriorWorkQueue]:
        if ids:
            with Session() as sess:
                return sess.query(InteriorWorkQueue).filter(InteriorWorkQueue.task_id.in_(ids)).order_by(
                    InteriorWorkQueue.vehicle_task_begin_time.asc()).all()
        return []


class PreworkWorkService(object):
    """
    预作业任务
    """

    @staticmethod
    def get_work_queue(ids: list[str]) -> list[PreworkWorkQueue]:
        if ids:
            with Session() as sess:
                return sess.query(PreworkWorkQueue).filter(PreworkWorkQueue.task_id.in_(ids)).order_by(
                    PreworkWorkQueue.vehicle_task_begin_time.asc()).all()
        return []


class TallyWorkService(object):
    """
    理货任务
    """

    @staticmethod
    def get_work_queue(ids: list[str]) -> list[TallyWorkQueue]:
        if ids:
            with Session() as sess:
                return sess.query(TallyWorkQueue).filter(TallyWorkQueue.task_id.in_(ids)).order_by(
                    TallyWorkQueue.vehicle_task_begin_time.asc()).all()
        return []


if __name__ == '__main__':
    # 发货任务
    dws = DeliveryWorkService()
    data_list = dws.get_work_queue(["4d193cd2786147cab5e7292ef1e19af4", "0ae4ebc708c54db3aedbfb12bc6db5a9"])
    print(f'[PC] 发货任务： {[_.task_id for _ in data_list]}')
    # 在库任务
    iws = InteriorWorkService()
    data_list = iws.get_work_queue(["16c6ad5bbdff4bb2a686929c7840b05f", "96b0c9ba4bbd4e8cb81a090c0a3989cd"])
    print(f'[PC] 在库任务：{[_.task_id for _ in data_list]}')
    # 预作业任务
    pws = PreworkWorkService()
    data_list = pws.get_work_queue(["2b9bc46e7a9e40e4bc6a03f771cs737f", "9e69c6c237724d648de5069e9c8b933"])
    print(f'[PC] 预作业任务：{[_.task_id for _ in data_list]}')
    # 理货任务
    tws = TallyWorkService()
    data_list = tws.get_work_queue([""])
    print(f'[PC] 理货任务：{[_.task_id for _ in data_list]}')
